﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.ServiceModel;
using WCFServiceWebRole1.Services;
using System.ServiceModel.Web;
using System.ServiceModel.Description;
using GlobalObjects;
using WCFServiceWebRole1.DataObjects;
using System.Diagnostics;

namespace IotWebService_Intergration_Test
{
    [TestClass]
    public class UserServiceTests
    {
        static readonly string ServiceBaseAddress = "http://localhost:8000/Services/users.svc";
        static ServiceHost host;
        Iusers proxy;
        static User testUser;
        
        static int testUserid;

        [ClassInitialize]
        public static void ClassInitialize(TestContext context)
        {
            testUser = new User()
            {
                Country = "India",
                Email = "integrationtest@gmail.com",
                FirstName = "Integration",
                LastName = "Test",
                Organisation = "Microsoft",
                Password = "testing",
                Purpose = "WCFRestTest",
              
                Title = "Mr.",
                Username = "usertest"
            };
            host = new ServiceHost(typeof(user));
            host.AddDefaultEndpoints();
            host.Open();
        }

        [ClassCleanup]
        public static void ClassCleanup()
        {
            host.Close();
        }

        [TestInitialize]
        public void Initialize()
        {
            WebChannelFactory<Iusers> factory = new WebChannelFactory<Iusers>(new Uri(ServiceBaseAddress));
            factory.Endpoint.Behaviors.Add(new WebHttpBehavior());
            proxy = factory.CreateChannel();

            //ChannelFactory<Iusers> factory = new ChannelFactory<Iusers>(new WebHttpBinding(), new EndpointAddress(ServiceBaseAddress));
            //factory.Endpoint.Behaviors.Add(new WebHttpBehavior());

         //   this.proxy = factory.CreateChannel();
          //  ((IClientChannel)proxy).Closed += delegate { factory.Close(); };
        }

        [TestCleanup]
        public void Cleanup()
        {
           // ((IClientChannel)this.proxy).Close();
        }

        #region addUser Method

        //testing addUser Method - Path 1
        [TestMethod]
        [ExpectedException(typeof(ProtocolException), "Raise exception when service returns exception")]
        public void addNewUser_inValid_EmptyFields()
        {
            User invalidUser = new User()
            {
                Country = "India",
                Email = "",
                FirstName = "Integration",
                LastName = "Test",
                Organisation = "Microsoft",
                Password = "testing",
                Purpose = "WCFRestTest",
            
                Title = "Mr.",
                Username = "usertest"
            };
            UserDetailsResponse createdUser = proxy.addUser(invalidUser);
           // testUserid = createdUser.response.Id;
            Assert.AreNotEqual(proxy.getUserByUserId(createdUser.response.Id.ToString()).response.Username, testUser.Username);
        }

        //testing addUser Method - Path 2
        [TestMethod]
        [ExpectedException(typeof(ProtocolException), "Raise exception when service returns exception")]
        public void addNewUser_inValid_MissingFields()
        {
            User invalidUser = new User()
            {
                Country = "India",
                Email = "integrationtest@gmail.com",
                FirstName = "Integration",
                LastName = "Test",
                Organisation = "Microsoft",
                Purpose = "WCFRestTest",
          
                Title = "Mr.",
                Username = "usertest"
            };
            UserDetailsResponse createdUser = proxy.addUser(invalidUser);
         //   testUserid = createdUser.response.Id;
            Assert.AreNotEqual(proxy.getUserByUserId(createdUser.response.Id.ToString()).response.Username, testUser.Username);
        }

        //testing addUser Method - Path 3
        [TestMethod]
        [ExpectedException(typeof(ProtocolException), "Raise exception when service returns exception")]
        public void addNewUser_inValid_NullFields()
        {
            User invalidUser = new User()
            {
                Country = "India",
                Email = "integrationtest@gmail.com",
                FirstName = "Integration",
                LastName = "Test",
                Organisation = "Microsoft",
                Password = "testing",
                Purpose = null,
           
                Title = "Mr.",
                Username = "usertest"
            };
            UserDetailsResponse createdUser = proxy.addUser(invalidUser);
        //    testUserid = createdUser.response.Id;
            Assert.AreNotEqual(proxy.getUserByUserId(createdUser.response.Id.ToString()).response.Username, testUser.Username);
        }

        //testing addUser Method - Path 4
        [TestMethod]
        public void addNewUser_valid()
        {
            UserDetailsResponse createdUser = proxy.addUser(testUser);
            testUserid = createdUser.response.Id;
            Assert.AreEqual(proxy.getUserByUserId(createdUser.response.Id.ToString()).response.Username, testUser.Username);
        }

        //testing addUser Method - Path 5
        [TestMethod]
        [ExpectedException(typeof(ProtocolException), "Raise exception when service returns exception")]
        public void addNewUser_inValid_userNameAlreadyExists()
        {
            UserDetailsResponse createdUser = proxy.addUser(testUser);
        }

        #endregion
  
        #region getUserByUserId 

        //testing getUserByUserId Method - Path 1
        [TestMethod]
        [ExpectedException(typeof(ProtocolException), "Raise exception when service returns exception")]
        public void getUserByUserId_inValid_userIdNAN()
        {
            UserDetailsResponse createdUser = proxy.getUserByUserId("hello");
        }

        //testing getUserByUserId Method - Path 2
        [TestMethod]
        [ExpectedException(typeof(ProtocolException), "Raise exception when service returns exception")]
        public void getUserByUserId_inValid_userIdNotExist()
        {
            UserDetailsResponse createdUser = proxy.getUserByUserId("0");
            Assert.AreNotEqual(createdUser.response.Username, "SomeName");
        }

        //testing getUserByUserId Method - Path 3
        [TestMethod]
        public void getUserByUserId_valid()
        {
            UserDetailsResponse createdUser = proxy.getUserByUserId(testUserid.ToString());
            Assert.AreEqual(createdUser.response.Username, testUser.Username);
        }

        #endregion

        #region updateUser

        //testing updateUser Method - Path 1
        [TestMethod]
        [ExpectedException(typeof(ProtocolException), "Raise exception when service returns exception")]
        public void updateUser_inValid_userNameNotExist()
        {
            UserDetails updateUser = new UserDetails()
            {
                Country = "India",
                EmailAddress = "integrationtest@gmail.com",
                FirstName = "Integration",
                LastName = "Test",
                Organization = "Microsoft",
                Purpose = "WCFRestTest",
             
                Title = "Mr.",
                Username = "usertest2",
                Id=testUserid
            };

            UserDetailsResponse updatedUser = proxy.updateUser("hello", updateUser);
            Assert.AreNotEqual(updatedUser.response.Username, testUser.Username);
        }

        //testing updateUser Method - Path 2
        [TestMethod]
        [ExpectedException(typeof(ProtocolException), "Raise exception when service returns exception")]
        public void updateUser_inValid_userIdConnotBeOmmitted()
        {
            UserDetails updateUser = new UserDetails()
            {
                Country = "India",
                EmailAddress = "integrationtest@gmail.com",
                FirstName = "Integration",
                LastName = "Test",
                Organization = "Microsoft",
                Purpose = "WCFRestTest",
             
                Title = "Mr.",
                Username = "usertest",
            };
            UserDetailsResponse updatedUser = proxy.updateUser("hello", updateUser);
        }


        //testing updateUser Method - Path 3
        [TestMethod]
        public void updateUser_inValid_EmptyFields()
        {
            UserDetails updateUser = new UserDetails()
            {
                Country = "India",
                EmailAddress = "",
                FirstName = "Integration",
                LastName = "Test",
                Organization = "Microsoft",
                Purpose = "WCFRestTest",
       
                Title = "Mr.",
                Username = "usertest",
                Id = testUserid
            };

            UserDetailsResponse updatedUser = proxy.updateUser(testUserid.ToString(), updateUser);
            Assert.AreEqual(updatedUser.response.EmailAddress, testUser.Email);
        }

        //testing updateUser Method - Path 4
        [TestMethod]
        public void updateUser_inValid_nullFields()
        {
            UserDetails updateUser = new UserDetails()
            {
                Country = "India",
                EmailAddress = "",
                FirstName = "Integration",
                LastName = "Test",
                Organization = null,
                Purpose = "WCFRestTest",
             
                Title = "Mr.",
                Username = "usertest",
                Id = testUserid
            };

            UserDetailsResponse updatedUser = proxy.updateUser(testUserid.ToString(), updateUser);
            Assert.IsNotNull(updatedUser.response.Organization);
            Assert.AreEqual(updatedUser.response.Organization, testUser.Organisation);

        }

        //testing updateUser Method - Path 5
        [TestMethod]
        [ExpectedException(typeof(ProtocolException), "Raise exception when service returns exception")]
        public void updateUser_inValid_changeUserName()
        {
            UserDetails updateUser = new UserDetails()
            {
                Country = "India",
                EmailAddress = "integrationtest@gmail.com",
                FirstName = "Integration",
                LastName = "Test",
                Organization = "Microsoft",
                Purpose = "WCFRestTest",
            
                Title = "Mr.",
                Username = "usertest2",
                Id=testUserid
            };
            UserDetailsResponse updatedUser = proxy.updateUser(testUserid.ToString(), updateUser);
        }

        //testing updateUser Method - Path 6
        [TestMethod]
        [ExpectedException(typeof(ProtocolException), "Raise exception when service returns exception")]
        public void updateUser_inValid_userIdNAN()
        {
            UserDetails updateUser = new UserDetails()
            {
                Country = "India",
                EmailAddress = "integrationtest@gmail.com",
                FirstName = "Integration",
                LastName = "Test",
                Organization = "Microsoft",
                Purpose = "WCFRestTest",
          
                Title = "Mr.",
                Username = "usertest",
                Id = testUserid
            };
            UserDetailsResponse updatedUser = proxy.updateUser("hello", updateUser);
        }

        //testing updateUser Method - Path 7
        [TestMethod]
        public void updateUser_valid()
        {
            bool success = false;
            UserDetails updateUser = new UserDetails()
            {
                Country = "India",
                EmailAddress = "integrationtest@gmail.com",
                FirstName = "Integration",
                LastName = "Test",
                Organization = "Microsoft Research",
                Purpose = "WCFRestTest",
           
                Title = "Mr.",
                Username = "usertest",
                Id = testUserid
            };
            try
            {
                UserDetailsResponse updatedUser = proxy.updateUser(testUserid.ToString(), updateUser);
                success = true;
            }
            catch (Exception ex) { }
            if (success)
            {
                testUser.Organisation = "Microsoft Research";
            }
            Assert.AreEqual("Microsoft Research",proxy.getUserByUserId(testUserid.ToString()).response.Organization);
        }

        #endregion

        #region CheckUserName

        //testing CheckUserName Method - Path 1
        [TestMethod]
        public void CheckUserNamer_valid_userNameAlreadyExist()
        {
           Assert.IsTrue(proxy.CheckUserName(testUser.Username ));
        }

        //testing CheckUserName Method - Path 2
        [TestMethod]
        public void CheckUserNamer_valid_userNameNotExist()
        {
            Assert.IsFalse(proxy.CheckUserName("hello"));
        }

        #endregion

        #region checkLogin

        //testing checkLogin Method - Path 1
        [TestMethod]
        [ExpectedException(typeof(ProtocolException), "Raise exception when service returns exception")]
        public void checkLogin_inValid_userNameNotexist()
        {
            UserLoginContract credentials = new UserLoginContract() { Username = "hello", Password = testUser.Password };
            UserDetailsResponse retrievedUser = proxy.checkLogin(credentials);
            Assert.AreEqual(retrievedUser.response.Username, testUser.Username);
        }

        //testing checkLogin Method - Path 2
        [TestMethod]
        [ExpectedException(typeof(ProtocolException), "Raise exception when service returns exception")]
        public void checkLogin_inValid_wrongPassword()
        {
            UserLoginContract credentials = new UserLoginContract() { Username = testUser.Username, Password = "WrongPassword" };
            UserDetailsResponse retrievedUser = proxy.checkLogin(credentials);
            Assert.AreNotEqual(retrievedUser.response.Username, testUser.Username);
        }

        //testing checkLogin Method - Path 3
        [TestMethod]
        public void checkLogin_Valid()
        {
            UserLoginContract credentials = new UserLoginContract() { Username = testUser.Username, Password = testUser.Password };
            UserDetailsResponse retrievedUser = proxy.checkLogin(credentials);
            Assert.AreEqual(retrievedUser.response.Username, testUser.Username);
        }

        #endregion

        #region ChangePassword

        //testing ChangePassword Method - Path 1
        [TestMethod]
        [ExpectedException(typeof(ProtocolException), "Raise exception when service returns exception")]
        public void ChangePassword_inValid_userIdNAN()
        {
            ChangePasswordContract changePassword = new ChangePasswordContract() { Id = testUserid, NewPassword = "newPassword", OldPassword = "testing" };
            bool success = false;     
            try
            {
                Assert.IsFalse(proxy.ChangePassword("hello", changePassword));
                success = true;
            }
            catch (Exception ex) { throw ex; }
            if (success)
            {
                testUser.Password = "newPassword";
            }
        }

        //testing ChangePassword Method - Path 2
        [TestMethod]
        [ExpectedException(typeof(ProtocolException), "Raise exception when service returns exception")]
        public void ChangePassword_inValid_userIdDoesNotMatch()
        {
            ChangePasswordContract changePassword = new ChangePasswordContract() { Id = testUserid, NewPassword = "newPassword", OldPassword = "testing" };
            bool success = false;
            try
            {
                Assert.IsFalse(proxy.ChangePassword("10", changePassword));
                success = true;
            }
            catch (Exception ex) { throw ex; }
            if (success)
            {
                testUser.Password = "newPassword";
            }
        }

        //testing ChangePassword Method - Path 3
        [TestMethod]
        public void ChangePassword_inValid_oldPasswordDoesNotMatch()
        {
            ChangePasswordContract changePassword = new ChangePasswordContract() { Id = testUserid, NewPassword = "newPassword", OldPassword = "wrongtesting" };
            bool success = false;
            try
            {
                Assert.IsFalse(proxy.ChangePassword(testUserid.ToString(), changePassword));
            }
            catch (Exception ex) { throw ex; }
 
        }

        //testing ChangePassword Method - Path 4
        [TestMethod]
        [ExpectedException(typeof(ProtocolException), "Raise exception when service returns exception")]
        public void ChangePassword_inValid_PasswordNullField()
        {
            ChangePasswordContract changePassword = new ChangePasswordContract() { Id = testUserid, NewPassword = "newPassword", OldPassword = "" };
            bool success = false;
            try
            {
                Assert.IsFalse(proxy.ChangePassword(testUserid.ToString(), changePassword));
                success = true;
            }
            catch (Exception ex) { throw ex; }
            if (success)
            {
                testUser.Password = "newPassword";
            }
        }

        //testing ChangePassword Method - Path 5
        [TestMethod]
        public void ChangePassword_valid()
        {
            ChangePasswordContract changePassword = new ChangePasswordContract() { Id = testUserid, NewPassword = "newPassword", OldPassword = "testing" };
            bool success = false;
            try
            {
                Assert.IsTrue(proxy.ChangePassword(testUserid.ToString(), changePassword));
                success = true;
            }
            catch (Exception ex) { }
            if (success)
            {
                testUser.Password = "newPassword";
            }
        }

        #endregion

        #region deleteUser

        //testing deleteUser Method - Path 1
        [TestMethod]
        [ExpectedException(typeof(ProtocolException), "Raise exception when service returns exception")]
        public void deleteUser_inValid_userIdNAN()
        {
            UserDeleteContract deleteUser = new UserDeleteContract()
            {
                Password = "testing",
                Id = testUserid
            };
            Assert.IsFalse(proxy.deleteUser("hello", deleteUser));
        }

        //testing deleteUser Method - Path 2
        [TestMethod]
        [ExpectedException(typeof(ProtocolException), "Raise exception when service returns exception")]
        public void deleteUser_inValid_userIdDoesNotMatch()
        {
            UserDeleteContract deleteUser = new UserDeleteContract()
            {
                Password = "testing",            
                Id = testUserid
            };
             Assert.IsFalse(proxy.deleteUser("10",deleteUser));  
        }

        //testing deleteUser Method - Path 3
        [TestMethod]
        [ExpectedException(typeof(ProtocolException), "Raise exception when service returns exception")]
        public void deleteUser_inValid_NullField()
        {
            UserDeleteContract deleteUser = new UserDeleteContract()
            {
                Password = null,
                Id = testUserid
            };
            Assert.IsFalse(proxy.deleteUser(testUserid.ToString(), deleteUser));
        }

        //testing deleteUser Method - Path 4
        [TestMethod]
        [ExpectedException(typeof(ProtocolException), "Raise exception when service returns exception")]
        public void deleteUser_inValid_emptyField()
        {
            UserDeleteContract deleteUser = new UserDeleteContract()
            {
                Password = "",
                Id = testUserid
            };
            Assert.IsFalse(proxy.deleteUser(testUserid.ToString(), deleteUser));
        }

        //testing deleteUser Method - Path 5
        [TestMethod]
        public void deleteUser_valid()
        {
            Debug.WriteLine("User ID" + testUserid);
            Debug.WriteLine("User Name" + testUser.Username);
            Debug.WriteLine("User Pasword" + testUser.Password);
            UserDeleteContract deleteUser = new UserDeleteContract()
            {
                Id = testUserid,
                Password = testUser.Password,
            };
            Assert.IsTrue(proxy.deleteUser(testUserid.ToString(), deleteUser));

            //UserDeleteContract deleteUser = new UserDeleteContract() { Id = 3202, Password = "newPassword" };
            //Assert.IsTrue(proxy.deleteUser("3202", deleteUser));
        }

        #endregion

    




    }
}
